package com.xcity.game.worldboss.model;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.LinkedHashSet;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.xcity.config.ConfigEx;
import com.xcity.db.entity.Player;
import com.xcity.game.combat.CombatTeam;
import com.xcity.game.npc.NpcTeamTemplate;
import com.xcity.game.npc.NpcTemplate;
import com.xcity.game.worldboss.WorldBossService;
import com.xcity.game.worldboss.template.WorldBossTemplate;

import naga.x.App;
import naga.x.util.IOUtils;

public class WorldBoss {

	/** boss等级 */
	private int level;
	/** 击打过该boss的玩家 */
	private LinkedHashSet<Long> hitList;
	/** boss血量 */
	private int[] hps;
	
	@JSONField(serialize = false)
	private WorldBossTemplate template;
	
	public WorldBoss() {}
	
	public WorldBoss(WorldBossTemplate template) {
		this.level = template.getLevel();
		this.hitList = new LinkedHashSet<Long>(64);
		this.hps = initHps(template);
		this.template = template;
	}

	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public LinkedHashSet<Long> getHitList() {
		return hitList;
	}

	public void setHitList(LinkedHashSet<Long> hitList) {
		this.hitList = hitList;
	}

	public int[] getHps() {
		return hps;
	}

	public void setHps(int[] hps) {
		this.hps = hps;
	}

	public WorldBossTemplate getTemplate() {
		return template != null ? template
				: (template = App.getApp().getServiceManager().get(WorldBossService.class).getBossTemplate(level));
	}
	
	@JSONField(serialize = false)
	public long getHp() {
		long val = 0;
		for (int hp : hps) {
			val += hp;
		}
		return val;
	}
	
	/**
	 * reduce the boss's hp
	 * @param delta
	 * @return true if the boss was died
	 */
	public boolean decHp(int[] delta) {
		boolean died = true;
		for (int i = 0; i < hps.length; i++) {
			int v = delta[i];
			if (v > 0) {
				hps[i] -= v;
				if (hps[i] > 0) {
					died = false;
				} else {
					hps[i] = 0;
				}
			}
		}
		return died;
	}
	
	public void addToHitList(Player player) {
		hitList.add(player.getId());
	}
	
	public void fireLevelUp() {
		WorldBossService service = App.getApp().getServiceManager().get(WorldBossService.class);
		int maxLvl = service.getBossMaxLevel();
		if (level < maxLvl) {
			template = service.getBossTemplate(++level); // level up
		}
		hitList.clear();
		hps = initHps(template);
	}
	
	public boolean wasDied() {
		for (int hp : hps) {
			if (hp > 0) {
				return false;
			}
		}
		return true;
	}
	
	
	private static int[] initHps(WorldBossTemplate template) {
		int[] hps = new int[CombatTeam.DEFAULT_TEAM_CAPACITY];
		NpcTeamTemplate npcTeam = template.getNpcTeam();
		hps[0] = npcTeam.getBoss().getMaxHp();
		NpcTemplate[] npcs = npcTeam.getNpcs();
		if (npcs != null) {
			for (int i = 0; i < npcs.length; i++) {
				hps[i + 1] = npcs[i].getMaxHp();
			}
		}
		return hps;
	}

	public static void serialize(WorldBoss boss) {
		File file = getSerializeFile();
		IOUtils.write(file, JSON.toJSONBytes(boss));
	}

	public static WorldBoss deserialize() {
		File file = getSerializeFile();
		if (file.exists()) {
			try (InputStream in = new BufferedInputStream(new FileInputStream(file), 10240)) {
				return JSON.parseObject(in, WorldBoss.class);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	private static File getSerializeFile() {
		ConfigEx config = App.getApp().getConfig();
		File file = new File(config.localDbDir, "worldBoss.db");
		return file;
	}

}
